home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
MACD 5
/
MACD 5.bin
/
workbench
/
libs
/
usergrouplib.lha
/
usergroup
/
getutent.c
< prev
next >
Wrap
C/C++ Source or Header
|
1992-09-02
|
12KB
|
529 lines
RCS_ID_C="$Id: getutent.c,v 4.1 1994/05/16 14:09:07 ppessi Exp $";
/*
* Login database functions
*
* Author: ppessi <Pekka.Pessi@hut.fi>
*
* This file is part of the AmiTCP/IP usergroup.library.
*
* Copyright © 1993 AmiTCP/IP Group, <AmiTCP-Group@hut.fi>
* Helsinki University of Technology, Finland.
*
* Created : Sun Nov 28 17:45:55 1993 ppessi
* Last modified: Mon May 16 12:57:05 1994 ppessi
*
* $Log: getutent.c,v $
* Revision 4.1 1994/05/16 14:09:07 ppessi
* Fixed some outdated typecasts
*
* Revision 2.4 1994/02/27 19:15:26 ppessi
* Removed getutsid() as obsoilete
*
* Revision 2.3 1994/02/22 03:01:12 ppessi
* Removed tty from logging information
*
* Revision 2.2 1994/02/17 12:11:55 ppessi
* Release 2
*
* Revision 2.1 1994/02/17 02:21:06 ppessi
* Saving before downgrading library
*
*/
/****** usergroup.library/getutent *******************************************
NAME
getutsid, getutent, setutent, endutent - utmp database operations
SYNOPSIS
#include <utmp.h>
utmpent = getutsid(sid)
D0 D0
struct utmp *getutsid(long);
utmpent = getutent()
D0
struct utmp *getutent(void);
setutent()
void setutent(void);
endutent()
void endutent(void);
FUNCTION
These functions operate on the utmp database. There is an utmp
entry for each active session. A session is started with login
command and finished with logout command.
The entry returned by each reading function is defined by the
structure utmp found in the include file <utmp.h>:
struct utmp {
long ut_time; \* the login time *\
long ut_sid; \* session ID *\
char ut_name[UT_NAMESIZE]; \* the login name *\
char ut_line[UT_LINESIZE]; \* the name of login device *\
char ut_host[UT_HOSTSIZE]; \* where the login originated *\
};
The getutsid() function search the utmp database for the given
session id, returning the first one encountered. The getutent()
function sequentially reads the utmp database. Both functions also
open the utmp database, if necessary.
The setutent() function opens the utmp database. The
endutent() function closes the utmp database. It is
recommended to call endutent() if the program won't access
utmp database any more.
RESULTS
The functions getutsid() and getutent() return a pointer to the utmp
entry if successful; if the end of database is reached or an error
occurs a null pointer is returned. The functions endutent() and
setutent() have no return value.
ERRORS
[ENOENT] -- no utmp entries were available.
SEE ALSO
BUGS
The getutent() and getutsid() function leave their result in an
internal static object and return a pointer to that object.
Subsequent calls to the same function will modify the same object.
Current implementation allows only one user to be logged in
concurrently.
*****************************************************************************
*
*/
#include "base.h"
#include "libfunc.h"
#include "credential.h"
#include <utmp.h>
#include <string.h>
#include <exec/memory.h>
#include <dos/dos.h>
#include <sys/time.h>
#define SINGLE_USER
ASM int R_gettimeofday(REG(a0) struct timeval *tvp,
REG(a1) struct timezone *tzp);
#ifdef SINGLE_USER
/*
* These are simple routines for single-user environment
*/
void CleanupUTMP(void)
{
}
static short already_read = 0;
SAVEDS ASM void R_endutent(void)
{
already_read = 0;
}
SAVEDS ASM void R_setutent(void)
{
already_read = 0;
}
SAVEDS ASM struct utmp *R_getutent(void)
{
if (!already_read) {
static struct utmp utentbuf[1];
already_read = 1;
*utentbuf = *CredentialBase->r_utmp;
return utentbuf;
}
SetErrno(ENOENT);
return NULL;
}
#else
static void lock_for_writing(void)
{
}
static void unlock_for_writing(void)
{
}
#define UTENTS 2
static short utent_left;
static struct utmp *utentbuf = NULL, *utent = NULL;
static BPTR utfile = NULL;
static LONG uttell;
void CleanupUTMP(void)
{
R_endutent();
if (utentbuf != NULL) {
FreeVec(utentbuf), utentbuf = NULL;
}
}
SAVEDS ASM void R_endutent(void)
{
if (utfile != NULL) {
Close(utfile), utfile = NULL;
}
}
SAVEDS ASM void R_setutent(void)
{
if (utentbuf == NULL)
utentbuf = AllocVec(sizeof(*utent) * UTENTS, MEMF_CLEAR | MEMF_PUBLIC);
if (utentbuf != NULL) {
utent_left = 0;
if (utfile == NULL) {
utfile = Open(_PATH_UTMP, MODE_READWRITE);
} else {
Seek(utfile, 0, OFFSET_BEGINNING);
}
}
}
SAVEDS ASM struct utmp *R_getutent(void)
{
if (utentbuf == NULL) {
R_setutent();
}
if (utfile) {
for (;;) {
if (utent_left == 0) {
LONG read;
uttell = Seek(utfile, 0, OFFSET_CURRENT);
read = Read(utfile, utentbuf, sizeof(*utent) * UTENTS);
utent = utentbuf;
if (read >= sizeof(*utent)) {
utent_left = read / sizeof(*utent);
} else {
break;
}
} else {
uttell += sizeof(*utent);
}
utent_left--;
if (utent->ut_time != 0)
return utent++;
utent++;
}
SetErrno(ENOENT);
} else {
if (utentbuf)
SetErrno(ENOENT);
else
SetErrno(ENOMEM);
}
return NULL;
}
SAVEDS ASM struct utmp *R_getutsid(REG(d0) pid_t sid)
{
struct utmp *ut;
for (R_setutent(); ut = R_getutent();) {
if (ut->ut_sid == sid)
return ut;
}
return NULL;
}
#endif
/****** usergroup.library/getlastlog *******************************************
NAME
getlastlog - get lastlog database entry
SYNOPSIS
#include <utmp.h>
lastlog = getlastlog(uid)
D0 D0
struct lastlog *getlastlog(uid_t);
FUNCTION
The getlastlog() function search the lastlog database for the given
user id. There should be an lastlog entry for each user. A lastlog
entry with ll_time being zero means that user has never logged in
this system.
The entry returned by getlastlog is defined by the structure lastlog
found in the include file <utmp.h>:
struct lastlog {
long ll_time; \* the login time *\
uid_t ll_uid; \* user ID *\
char ll_name[UT_NAMESIZE]; \* the login name *\
char ll_line[UT_LINESIZE]; \* the name of login device *\
char ll_host[UT_HOSTSIZE]; \* where the login originated *\
};
RESULTS
The function getlastlog() returns a pointer to the lastlog entry if
successful; if an error occurs a null pointer is returned.
ERRORS
[ENOENT] -- no lastlog entry was found
[EINVAL] -- the user ID was illegal
SEE ALSO
setlastlog()
BUGS
The getlastlog() function leaves its result in an internal static
object and return a pointer to that object. Subsequent calls to the
same function will modify the same object.
Current implementation stores only the lastlog data of the latest
user logged in.
*****************************************************************************
*
*/
#ifdef SINGLE_USER
SAVEDS ASM struct lastlog *R_getlastlog(REG(d0) uid_t uid)
{
static struct lastlog ll[1];
if (uid == CredentialBase->r_lastlog->ll_uid) {
*ll = *CredentialBase->r_lastlog;
} else {
bzero(ll, sizeof(*ll));
ll->ll_uid = uid;
}
return ll;
}
#else
static LONG lltell = 0;
SAVEDS ASM struct lastlog *R_getlastlog(REG(d0) uid_t uid)
{
static struct lastlog ll[1];
BPTR llfile = Open(_PATH_LASTLOG, MODE_OLDFILE);
int never = 1;
lltell = 0;
if (llfile) {
while (Read(llfile, ll, sizeof(*ll)) == sizeof(*ll)) {
lltell += sizeof(*ll);
if (ll->ll_uid == uid) {
never = 0;
break;
}
}
Close(llfile);
}
if (never) {
ll->ll_time = 0;
ll->ll_uid = uid;
ll->ll_name[0] = '\0';
ll->ll_line[0] = '\0';
ll->ll_host[0] = '\0';
lltell = -1;
}
return ll;
}
#endif
/****** usergroup.library/setlastlog ***************************************
NAME
setlastlog - login an user
SYNOPSIS
#include <utmp.h>
lastlogin = setlastlog(uid, name, console, host)
struct lastlog setlastlog(uid_t, char *, char *, char *);
FUNCTION
The setlastlog function is used to register user logging in. Each
time a user is logging in, the function setlastlog() should be
called to register that event.
INPUTS
uid -- the uid of user logging in
name -- the user login name
console -- the console handler name (from ug_GetConsole())
host -- the host which the user is logging in from
RESULTS
The setlastlog() function returns an success indicator, 0 if the
call was successful, -1 otherwise. The error code is set if an
error occurs.
ERRORS
The setlastlog() can have following error codes:
[EFAULT] -- the utmp entry cannot be accessed
[ENOMEM] -- the memory has been exhausted
[ENOENT] -- cannot access utmp database
BUGS
Current implementation stores only the lastlog data of the latest
user logged in.
FILES
SEE ALSO
getutent(), getlastlog()
*****************************************************************************
*/
#ifdef SINGLE_USER
/*
* This is somewhat simplified version
*/
SAVEDS ASM int
R_setlastlog(REG(d0) uid_t uid,
REG(a0) char *name, REG(a1) char *host)
{
short error = 0;
struct proc *p = procfind(NULL);
pid_t sid = p->p_session->s_leader;
if (name == NULL) {
error = EFAULT;
} else {
struct utmp utmp[1];
struct timeval now[1];
bzero((void *)utmp, sizeof(*utmp));
R_gettimeofday(now, NULL);
utmp->ut_time = now->tv_sec;
utmp->ut_sid = (long)sid;
strncpy(utmp->ut_name, name, sizeof(utmp->ut_name));
if (host)
strncpy(utmp->ut_host, host, sizeof(utmp->ut_host));
*CredentialBase->r_utmp = *utmp;
/*
* This trick requires that
* lastlog and utmp are essentially identical..
*/
utmp->ut_sid = (long) uid;
*CredentialBase->r_lastlog = *(struct lastlog *)utmp;
return 0;
}
SetErrno(error);
return -1;
}
#else /* SINGLE_USER */
SAVEDS ASM int
R_setlastlog(REG(d0) uid_t uid,
REG(a0) char *name, REG(a1) char *host)
{
short error = 0;
struct proc *p = procfind(NULL);
pid_t sid = p->p_session->s_leader;
if (name == NULL || con == NULL) {
error = EFAULT;
} else {
struct utmp *oldut, utmp[1];
struct timeval now[1];
bzero((void *)utmp, sizeof(*utmp));
R_gettimeofday(now, NULL);
utmp->ut_time = now->tv_sec;
utmp->ut_sid = sid;
strncpy(utmp->ut_name, name, sizeof(utmp->ut_name));
if (sid != 0)
strncpy(utmp->ut_line, con, sizeof(utmp->ut_line));
else
strcpy(utmp->ut_line, "ALL");
if (host)
strncpy(utmp->ut_host, host, sizeof(utmp->ut_host));
R_setutent();
/* Writing lock */
lock_for_writing();
if (utentbuf == NULL) {
error = ENOMEM;
} else if (utfile == NULL) {
error = ENOENT;
} else {
LONG utslot = -1;
while (oldut = R_getutent()) {
if (oldut->ut_sid == sid) {
utslot = uttell;
break;
}
if (oldut->ut_time == 0 && utslot == -1) {
utslot = uttell;
}
}
if (oldut == NULL)
utslot = uttell;
Seek(utfile, uttell, OFFSET_BEGINNING);
Write(utfile, utmp, sizeof(*utmp));
}
R_endutent();
{
BPTR llfile = Open(_PATH_LASTLOG, MODE_READWRITE);
utmp->ut_sid = (long)uid;
if (llfile) {
if (lltell > 0) {
Seek(llfile, lltell, OFFSET_BEGINNING);
} else {
LONG tell;
Seek(llfile, 0, OFFSET_END);
tell = Seek(llfile, 0, OFFSET_CURRENT);
tell = (tell / sizeof(*utmp)) * sizeof(*utmp);
Seek(llfile, tell, OFFSET_BEGINNING);
}
Write(llfile, utmp, sizeof(*utmp));
Close(llfile);
}
}
unlock_for_writing();
}
if (error != 0) {
SetErrno(error);
return NULL;
} else {
return ll;
}
}
#endif